namespace mgp.ads {

    export class WxVideoAd extends VideoAd {

        protected _videoAd: wx.RewardedVideoAd;

        /** 是否是用户主动准备调用激励视频播放 */
        protected _readyPlayVideo = false;
        /** 视频是否在加载中 */
        protected _isVideoLoading = false;
        protected _isVideoLoadOk = false;

        protected _timeKey: number;

        protected _successFun: () => void;
        protected _cancelFun: () => void;
        protected _completeFun: () => void;

        protected _crtAdIdx = 0;// 当前需要从ids里面取数据的idx

        constructor() {
            super();
            this._hasVideo = true;
        }

        setInfo(info: IVideoInfo) {
            this._info = info || {
                ids: []
            };
            if (isNaN(this._info.testHasVideoTime)) this._info.testHasVideoTime = 60;
        }
        set hasVideo(v: boolean) {
            this._hasVideo = v;
            if (!v) {
                // 如果拉取不到视频，需要每隔一段时间去拉取一下，判断是否真的没有视频了
                this._timeKey = timerOnce(this._info.testHasVideoTime * 1000, this, this._chkHasVideoTimeFunc, [], true, this._timeKey)
            }
        }
        get hasVideo() {
            return this._hasVideo;
        }
        protected _chkHasVideoTimeFunc() {
            if (this._isVideoLoading) return;
            this.loadVideoAd()
        }

        protected _getCrtIdx() {
            this._crtAdIdx++;
            if (this._crtAdIdx >= this._info.ids.length) {
                this._crtAdIdx = 0;
            }
            return this._crtAdIdx;
        }

        showVideoAd(success: () => void, cancel?: () => void, complete?: () => void) {
            if (adModule.state == AdState.NoAd) {
                debugLog('广告状态设置为了未上线状态，所以不显示')
                return;
            }
            if (!this._info || !this._info.ids || !this._info.ids.length) {
                debugWarn('未设置激励视频数据')
                return;
            }
            if (!wx.createRewardedVideoAd) {
                debugLog('当前环境不支持视频接口')
                return;
            }
            if (this._readyPlayVideo) {
                debugLog('正在准备视频中')
                return;
            }
            this._successFun = success;
            this._cancelFun = cancel;
            this._completeFun = complete;
            this._readyPlayVideo = true;
            // 因为一创建就会去拉取，所以这里要加上全局预加载
            if (!!this._info.preload) this._info.preload();
            debugLog('====> 1')
            if (!this._videoAd) {
                debugLog('====> 2')
                this._videoAd = this._getVideoAd();
                debugLog('====> 3')
                this._createdAd();// 创建完毕video后需要的操作,因为wx是创建完毕后，就开始load，ov之类的平台，需要手动调用load
                debugLog('====> 4')
            } else {
                debugLog('====> 5')
                if (this._isVideoLoadOk) {
                    debugLog('====> 6')
                    this._videoPlay()
                } else {
                    debugLog('====> 7')
                    this.loadVideoAd();
                }
            }
        }
        protected _createdAd() {

        }
        loadVideoAd() {
            this._videoAd = this._getVideoAd();
            this._videoAd.load();
            this._isVideoLoading = true;
        }

        protected _destroy() {
            debugLog('destory video ad')
            if (!this._videoAd) return;
            this._removeListener();
            if (!!this._videoAd['destroy']) this._videoAd['destroy']()
            this._videoAd = null;
            this._readyPlayVideo = false;
            this._successFun = null;
            this._cancelFun = null;
            this._completeFun = null;
        }

        protected _getVideoAd(id?: string) {
            if (!this._videoAd) {
                let idx = this._getCrtIdx();
                debugLog('video idx', idx);
                this._videoAd = wx.createRewardedVideoAd({
                    adUnitId: id || this._info.ids[idx],
                    multiton: false
                });
                this._addListener();
                debugLog('ad', this._videoAd);
            }
            return this._videoAd;
        }

        protected _addListener() {
            if (!this._videoAd) return;
            this._videoAd.onError(this._onVideoErr.bind(this))
            this._videoAd.onLoad(this._onVideoLoaded.bind(this))
            this._videoAd.onClose(this._onVideoClose.bind(this))
        }
        protected _removeListener() {
            if (!this._videoAd) return;
            this._videoAd.offClose(this._onVideoClose.bind(this))
            this._videoAd.offError(this._onVideoErr.bind(this))
            this._videoAd.offLoad(this._onVideoLoaded.bind(this))
        }
        protected _onVideoErr(err) {
            debugLog('激励视频拉取失败', err)
            if (!!this._info.loadErr) this._info.loadErr(err);
            if (!!this._cancelFun) this._cancelFun()
            this._readyPlayVideo = false;
            this._isVideoLoading = false;
            this._isVideoLoadOk = false;
            this._destroy();
        }
        protected _onVideoLoaded() {
            debugLog('激励视频拉取成功', this._videoAd)
            this._isVideoLoading = false;
            this.hasVideo = true;
            if (!this._videoAd) return;
            this._isVideoLoadOk = true;
            if (!!this._info.loadSuccess) this._info.loadSuccess();
            if (!this._readyPlayVideo) {
                return;
            }
            this._videoPlay()
        }
        protected _videoPlay() {
            debugLog('_videoPlay', this._videoAd)
            if (!this._videoAd) return;
            this._videoAd.show().then(() => {
                debugLog('激励视频开始播放')
                if (!!this._info.startPlay) this._info.startPlay();
                this._readyPlayVideo = false;
            }).catch(err => {
                this.loadVideoAd()
            })
            this._isVideoLoadOk = false;
        }
        protected _onVideoClose(res) {
            // 用户点击了【关闭广告】按钮
            // 小于 2.1.0 的基础库版本，res 是一个 undefined
            if (res && res.isEnded || res === undefined) {
                // 正常播放结束，可以下发游戏奖励
                debugLog('正常播放结束，可以下发游戏奖励')
                if (!!this._successFun) this._successFun()
                if (!!this._info.getReward) this._info.getReward();
            } else {
                // 播放中途退出，不下发游戏奖励
                debugLog('播放中途退出，不下发游戏奖励')
                if (!!this._cancelFun) this._cancelFun()
                if (!!this._info.videoCancel) this._info.videoCancel();
            }

            debugLog('视频关闭')
            this._readyPlayVideo = false;
            if (!!this._completeFun) this._completeFun()
            if (!!this._info.videoComplete) this._info.videoComplete();

            if (this._info.closeIsDestroy) {
                // 关闭即销毁
                this._readyPlayVideo = false;
                this._isVideoLoading = false;
                this._isVideoLoadOk = false;
                this._destroy();
            }
        }
    }
}